package com.auxgroup.hr.front.site.co.process;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.auxgroup.hr.front.site.co.BaseWfCO;
import com.auxgroup.hr.front.site.inteceptor.SessionGain;
import com.auxgroup.hr.front.site.vo.process.WfPlaveDtlReqVO;
import com.auxgroup.hr.front.site.vo.process.WfPlaveDtlRespTableVO;
import com.auxgroup.hr.front.site.vo.process.WfPlaveDtlRespVO;
import com.auxgroup.hr.front.site.vo.process.WfPlaveHdrRespVO;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONArray;
import com.auxgroup.hr.front.commons.BaseRetCode;
import com.auxgroup.hr.front.commons.enums.WfActionTypeEnum;
import com.auxgroup.hr.front.commons.enums.WfStatusEnum;
import com.auxgroup.hr.front.commons.enums.WfTypeEnum;
import com.auxgroup.hr.front.commons.utils.Bean2MapUtils;
import com.auxgroup.hr.front.commons.utils.DateUtils;
import com.auxgroup.hr.front.commons.vo.BaseResponseVO;
import com.auxgroup.hr.front.commons.vo.UserDTO;
import com.auxgroup.hr.front.dao.domain.PsCAppStepInst;
import com.auxgroup.hr.front.dao.domain.PsCWfPlaveDtl;
import com.auxgroup.hr.front.dao.domain.PsCWfSelHdr;
import com.auxgroup.hr.front.service.comm.SysDictService;
import com.auxgroup.hr.front.service.process.ProcessService;
import com.auxgroup.hr.front.service.process.WfFileService;
import com.auxgroup.hr.front.service.process.WfSelHdrService;
import com.auxgroup.hr.front.site.co.BaseCO;
import com.auxgroup.hr.front.site.inteceptor.SessionGain;
import com.auxgroup.hr.front.site.vo.process.WfPlaveDtlReqVO;
import com.auxgroup.hr.front.site.vo.process.WfPlaveDtlRespTableVO;
import com.auxgroup.hr.front.site.vo.process.WfPlaveDtlRespVO;
import com.auxgroup.hr.front.site.vo.process.WfPlaveHdrRespVO;
import com.auxgroup.hr.front.ws.ProcessApplyQueDTO;

/**
 * 销假申请CO
 * 
 * @author wangchangyun
 * @version 创建时间：180527
 */
@RestController
@RequestMapping("${auxgroup.hr.contextPath}/wfselhdr")
public class WfSelHdrCO extends BaseWfCO {

	private static final Logger logger = LoggerFactory.getLogger(WfSelHdrCO.class);

	@Autowired
	public WfSelHdrService  wfSelHdrService;



	@GetMapping(value="/getWfSelHdr")
	public BaseResponseVO getWfSelHdr(String cTransactionNbr,@SessionGain("user") UserDTO user){
		if(StringUtils.isBlank(cTransactionNbr)){
			return buildRespone(BaseRetCode.CODE_ERROR_REQUEST_PARAM_NULL);
		}
		PsCWfSelHdr selHdr =  wfSelHdrService.getSelHdrInfo(cTransactionNbr);
		if(selHdr==null){
			return buildRespone(BaseRetCode.CODE_ERROR_PROCESS_NOT_EXIST);
		}
		WfPlaveHdrRespVO respVO = objectMapper.map(selHdr, WfPlaveHdrRespVO.class);
		//请假事由
//		respVO.setLeaveInfo(selHdr.getcOtherExplain());
		List<PsCWfPlaveDtl> dtls = wfSelHdrService.getLaveDtls(cTransactionNbr);
		buildRespDtls(dtls,respVO);
		fillBaseWfInfo(user, selHdr, respVO);
		return buildRespone(respVO);
	}
	
	
	
	private void buildRespDtls(List<PsCWfPlaveDtl> dtls,WfPlaveHdrRespVO respVO){
		List<WfPlaveDtlRespVO> leaves = new ArrayList<WfPlaveDtlRespVO>();
		WfPlaveDtlRespTableVO tableVo;
		WfPlaveDtlRespVO respVo;
		if(dtls!=null&&!dtls.isEmpty()){
			for (PsCWfPlaveDtl dtl : dtls) {
				Map<String, Object> dtlmap = buildDictFieldFromObject(dtl);
				tableVo = new WfPlaveDtlRespTableVO();
				Bean2MapUtils.transMap2Bean(dtlmap, tableVo);
				respVo = objectMapper.map(tableVo, WfPlaveDtlRespVO.class,"wfPlaveDtlRespCopy");
				leaves.add(respVo);
			}
		}
	}
	
	
	/**
	 * 创建销假流程
	 * @param user
	 * @return
	 */
	@PostMapping(value="/saveSel")
	public BaseResponseVO saveWfSelHdr(String laveReqs,String leaveInfo,String cTransactionNbr,@SessionGain("user") UserDTO user){
		logger.info("PrcHdr save param:{}",laveReqs);
        if(laveReqs==null||laveReqs.isEmpty()){
        	return buildRespone(BaseRetCode.CODE_ERROR_REQUEST_PARAM_NULL.getRetCode(),"保存入参不能为空");
        }
		
        List<PsCWfPlaveDtl> dtls = buildDtls(laveReqs);
        if(StringUtils.isBlank(cTransactionNbr)){
        	cTransactionNbr = processService.getTranNum();
        	if(StringUtils.isBlank(cTransactionNbr)){
        		return buildRespone(BaseRetCode.CODE_ERROR_GET_TRANSACTION_NBR_FAILED);
        	}
        }
        PsCWfSelHdr selHdr = wfSelHdrService.saveSelHdrInfo(dtls,user,cTransactionNbr,leaveInfo);
        if(selHdr!=null){
        	ProcessApplyQueDTO requestDTO = new ProcessApplyQueDTO();
        	if(WfStatusEnum.WF_STATUS_S.getStatus().equals(selHdr.getcWfStatus())){
        		requestDTO.setC_ACTION_TYPE(WfActionTypeEnum.WF_ACTION_SUBMIT.getAction());
        	}else{
        		requestDTO.setC_ACTION_TYPE(WfActionTypeEnum.WF_ACTION_RESUBMIT.getAction());
        	}
            requestDTO.setC_TRANSACTION_NBR(cTransactionNbr);
            requestDTO.setC_USERID(user.getOprId());
            requestDTO.setC_WF_TYPE(WfTypeEnum.WF_STYPE_SEL.getType());
            Map<String, String> approveResult = processService.apply(requestDTO);
            if(approveResult==null||approveResult.isEmpty()){
    			return buildRespone(BaseRetCode.CODE_ERROR_PROCESS_APPLY_FAIL);
    		}
            if("0".equals(approveResult.get("C_MSG_CODE"))){
            	return buildRespone(cTransactionNbr);
            }else{
            	//只有初次发起时，发起失败才删除数据
            	if(WfStatusEnum.WF_STATUS_S.getStatus().equals(selHdr.getcWfStatus())){
            		wfSelHdrService.delSelHdr(cTransactionNbr);
            	}
            	return buildRespone(approveResult.get("C_MSG_CODE"), approveResult.get("C_MSG_TEXT"));
            }
        }else{
        	return buildRespone(BaseRetCode.CODE_ERROR_PROCESS_APPLY_FAIL);
        }
	}
	
	/**
	 * 构建数据库类
	 * @return
	 */
	private  List<PsCWfPlaveDtl> buildDtls(String laveReqInfo){
		JSONArray reqs = JSONArray.parseArray(laveReqInfo);
		List<WfPlaveDtlReqVO> laveReqs = new ArrayList<WfPlaveDtlReqVO>();
		for (int i = 0; i < reqs.size(); i++) {
			WfPlaveDtlReqVO reqVo = reqs.getObject(i, WfPlaveDtlReqVO.class);
			laveReqs.add(reqVo);
		}
		List<PsCWfPlaveDtl> dtls = new ArrayList<PsCWfPlaveDtl>();
		if(laveReqs!=null&&!laveReqs.isEmpty()){
			PsCWfPlaveDtl dtl = null;
			for (WfPlaveDtlReqVO reqVo : laveReqs) {
				dtl = objectMapper.map(reqVo, PsCWfPlaveDtl.class,"wfPlaveDtlCopy");
				if(StringUtils.isNotBlank(reqVo.getStartDTTM())){
					String startdttm = DateUtils.format(reqVo.getStartDate(), DateUtils.FORMAT_DEFAULT)+" "+reqVo.getStartDTTM()+":00";
					dtl.setCStartDttm(Timestamp.from(DateUtils.parseDate(startdttm, DateUtils.FORMAT_YYYYMMDDHHMISS).toInstant()));
				}
				if(StringUtils.isNotBlank(reqVo.getEndDTTM())){
					String enddttm = DateUtils.format(reqVo.getEndDate(), DateUtils.FORMAT_DEFAULT)+" "+reqVo.getEndDTTM()+":00";
					dtl.setCEndDttm(Timestamp.from(DateUtils.parseDate(enddttm, DateUtils.FORMAT_YYYYMMDDHHMISS).toInstant()));
				}
				//构建销假时长
				buildDurationDays(dtl);
				dtls.add(dtl);
			}
		}
		return dtls;
	}
	
	/**
	 * 构建休假时长
	 * @param dtl
	 */
	private void buildDurationDays(PsCWfPlaveDtl dtl){
		//以天为单位
		if("D".equals(dtl.getCLevaeUnit())){
			if("A".equals(dtl.getCLeaveInterval())){
				dtl.setCDurationDays(new BigDecimal(-1));
			}else{
				dtl.setCDurationDays(new BigDecimal(-0.5));
			}
		}
		//以小时为单位
		if("H".equals(dtl.getCLevaeUnit())){
			Long startTime = DateUtils.format2Date(dtl.getCStartDttm(), DateUtils.FORMAT_HHMMSS).getTime();
			Long endTime = DateUtils.format2Date(dtl.getCEndDttm(), DateUtils.FORMAT_HHMMSS).getTime();
			Long between = endTime-startTime;
			String hour = new DecimalFormat("#.00").format(between/3600000);
			if("A".equals(dtl.getCEnddttmMode())){
				dtl.setCDurationDays(new BigDecimal(hour).multiply(new BigDecimal(-1)));
			}
			
			if("B".equals(dtl.getCEnddttmMode())){
				dtl.setCDurationDays(new BigDecimal(hour).add(new BigDecimal(24)).multiply(new BigDecimal(-1)));
			}
		}
	}


	@Override
	protected Set<String> getAuthFileds() {
		return null;
	}
}
